package queue.array;


import queue.QueueInterface;
import java.util.NoSuchElementException;


public class ArrayQueue<T> implements QueueInterface<T> {
    private ArrayElement[] arr;
    private int freeIndex;

    public ArrayQueue() {
        this.arr = new ArrayElement [10];
    }

    public ArrayQueue(int startLength){
        this.arr = new ArrayElement[startLength];
    }

    /*
      After first ArrayElement was added
      all of next ArrayElements should contain the same class values.
      Else the method throws the IllegalArgumentException.
    */
    @Override
    public boolean offer(T value) {
        if (freeIndex != 0 &&
                value.getClass() != arr[0].getValue().getClass()) throw new IllegalArgumentException();

        if (freeIndex >= arr.length) increaseArray();

        arr[freeIndex] = new ArrayElement<>(value);
        freeIndex++;
        return arr[freeIndex -1]!=null;
    }

    private void increaseArray (){
        ArrayElement[] tmp = new ArrayElement [(arr.length*3)/2];
        System.arraycopy(arr, 0, tmp, 0, arr.length);
        arr = tmp;
    }

    @Override
    public T peek() {
        ArrayElement<T> returned = arr[0];
        if (returned == null) return null;
        return returned.getValue();
    }

    @Override
    public T element() {
        T returned = peek();
        if (returned == null) throw new NoSuchElementException();
        return returned;
    }

    @Override
    public T poll() {
        ArrayElement<T> returned = arr[0];
        System.arraycopy(arr, 1, arr, 0, --freeIndex);
        if (returned == null) return null;
        return returned.getValue();
    }

    @Override
    public T remove() {
        T returned = poll();
        if (returned == null) throw new NoSuchElementException();
        return returned;
    }

    @Override
    public String toString() {
        String str = "";
        for (int i=0; i < freeIndex; i++){
            str = str + arr[i].getValue();
            if (i < freeIndex-1) str = str + " <- ";
        }
        return str;
    }
}
